<script lang="ts" setup>
import { onPageScroll, onReady } from '@dcloudio/uni-app'
import { useScrollUpdownBottomContent, useWebsocket, useFormat } from '@/hooks'
import { useSubPage } from './composables'
import { ref } from 'vue'
import {
  getDialogueTopicDetail,
  insertChart,
  deleteChart,
  selectChart,
  uploadAudio,
  getChat,
} from '@/services/api'
import { onLoad, onShow, onUnload, onHide } from '@dcloudio/uni-app'
import { BASE_URL } from '@/config'
import { xmContainer } from '@/components/xm-container'
const setTitle = ref('')
const pageId = ref<Number>(0)
const { style: authInfoScrollStyle, scrollHandle: authInfoScrollHandle } =
  useScrollUpdownBottomContent('up', 80)
const {
  connectWebSocket,
  handleClickVideo,
  handleCloseVideo,
  base64toJson,
  webSocketSend,
  webSocketSendMp3,
  textTranslate,
  handleDebounce,
  toBase64,
} = useWebsocket()
const { encodeWAV, hexToString, buf2hex } = useFormat()
const isUnload = ref(false)
const requestStatus = ref(false)
const commentText = ref<any>('hi')
const recordList = ref<Array>([])
const animation = ref(false)
const detailObj = ref({})
const recorderManager = uni.getRecorderManager()
const innerAudioContext = uni.createInnerAudioContext()
innerAudioContext.autoplay = true
const showPopup = ref(false)
const isAnimation = ref(false)
const isHasHistory = ref(false)
const prologue = ref('')
const allTipsList = ref()
const tipsList = ref([])
const curPromptTips = ref()
const loading = ref(false)
const frameBufferList = ref([])
const playIconPng = ref('../../../static/imgs/play-black.png')
const playWhiteIconPng = ref('../../../static/imgs/play-white.png')
const playWhiteIconGif = ref('../../../static/imgs/play_white.gif')
const playIconGif = ref('../../../static/imgs/play_icon.gif')
const translateBlack = ref('../../../static/imgs/icons/translate_black.png')
const translateBlue = ref('../../../static/imgs/icons/translate_blue.png')
const skillsMessage = ref({
  platform: 'gpt',
  messages: [],
})
const speakValue = ref('')
const platform = ref('gpt') // gpt/kimi/qwen/rag
const handleClose = () => {
  showPopup.value = false
}
const loadingStatus = ref('none')
const handleClick = (type: string, value: string, index, source) => {
  switch (type) {
    case 'reload':
	if(loadingStatus.value == 'loading'){
		  uni.showToast({
		  title: 'Ai回复中...',
          icon: 'none',
		})
		return;
	}
      handleCloseVideo()
      isAnimation.value = true
      handleDebounce(() => {
        deleteChart(pageId.value).then((res) => {
          const { code, data } = res
          if (code === 0) {
            isAnimation.value = false
            recordList.value = []
            tipsList.value = []
            skillsMessage.value.messages = [
              {
                content: curPromptTips.value,
                role: 'system',
              },
            ]
            recordList.value.push({
              type: 1,
              origin: prologue.value,
              result: '',
              filename: '',
              isTranslate: false,
            })
            let params = {
              id: pageId.value,
              chat: prologue.value,
              role: 1,
              star: 0,
            }
            insertChart(params).then((res) => {})
            getChatAiTag(prologue.value)
               //自动播放ai第一句
              if (recordList.value.length === 1) {
                onplayTitle(recordList.value[0].origin, 'English',0)
              }
          }
        })
      }, 500)
      break
    case 'open':
      showPopup.value = true
      break
    case 'send':
      recordList.value.push({
        type: 2,
        origin: value,
        result: '',
        isTranslate: false,
      })
      // console.log( recordList.value," recordList.value")
      //将当前的ai回答语句传给服务端保存
      let params = {
        id: pageId.value,
        chat: value,
        role: 2,
        star: 0,
      }
      insertChart(params).then((res) => {})
      tipsList.value = []
      showPopup.value = false
      setSkills(value, 'user')
      break
    case 'close':
      uni.navigateBack()
      break
    case 'play':
      handleDebounce(() => {
        let strValue = value.origin || value.line
        if (![null, undefined, ''].includes(value.audio_url)) {
          if (source == 1) {
            recordList.value = recordList.value.map((item, i) => {
              return {
                ...item,
                isPlay: i === index,
              }
            })
          }
          if (source == 2) {
            tipsList.value = tipsList.value.map((item, i) => {
              return {
                ...item,
                isPlay: i === index,
              }
            })
          }
          handleClickVideo(value.audio_url).then(() => {
            if (source == 1) {
              recordList.value[index].isPlay = false
            }
            if (source == 2) {
              tipsList.value[index].isPlay = false
            }
          })
          return
        }
        webSocketSendMp3(strValue, 'English').then((res) => {
	      clearStop()
          if (source == 1) {
            recordList.value = recordList.value.map((item, i) => {
              return {
                ...item,
                isPlay: i === index,
              }
            })
          }
          if (source == 2) {
            tipsList.value = tipsList.value.map((item, i) => {
              return {
                ...item,
                isPlay: i === index,
              }
            })
          }
          let newArr: Iterable<number> = []
          res.map((item, index) => {
            const arrayBuffer = wx.base64ToArrayBuffer(item)
            const newBuffer = new Uint8Array(arrayBuffer)
            newArr.push(...newBuffer)
          })
          let uint8Array = new Uint8Array(newArr)
          const newUrl = wx.createBufferURL(uint8Array.buffer)
          if (source == 1) {
            recordList.value[index].audio_url = newUrl
          }
          if (source == 2) {
            tipsList.value[index].audio_url = newUrl
          }
          handleClickVideo(newUrl).then(() => {
            if (source == 1) {
              recordList.value[index].isPlay = false
            }
            if (source == 2) {
              tipsList.value[index].isPlay = false
            }
          })
        })
      }, 500)
      break
    case 'fanyi':
      textTranslate(value)
        .then(
          (res) => {
            tipsList.value[index].translate = res
            tipsList.value[index].isTranslate = true
          },
          () => {
            translateLongTip()
          }
        )
        .catch(() => {
          translateLongTip()
        })
      autoScroll()
      break
  }
}
onUnload(() => {
  isUnload.value = true
  handleCloseVideo()
})
onHide(() => {
  handleCloseVideo()
})
onReady(() => {
  autoScroll()
})
onLoad((option: any) => {
  pageId.value = Number(option.id)
  startWatch()
  init()
})

const goBack = ()=>{
  uni.navigateBack({delta: 1})
}
const autoScroll = () => {
  setTimeout(function () {
    uni.pageScrollTo({
      scrollTop: 10000, // 假设页面很长，滚动到一个很大的值，从而滚动到底部
      duration: 300, // 滚动动画时长，默认300ms
    })
  }, 100)
}

const init = async () => {
  const data = await getDetail(pageId.value)
  setTimeout(function () {
    loading.value = true
  }, 500)
  const isNew = await getHistoryChat()
  Promise.all([data, isNew]).then((result) => {
    skillsMessage.value.messages.push(
      {
        content: prologue.value,
        // content: 'Flora, you are the tallest in the family.',
        role: 'system',
      },
      {
        content: 'like you!',
        role: 'assistant',
      }
    )
    recordList.value.push({
      type: 1,
      origin: prologue.value,
      result: '',
      filename: '',
      isTranslate: false,
    })
	onplayTitle(prologue.value, 'English',0) //默认第一句播放
    getChatAiTag(prologue.value)
  })
  // return
  // const isNew = await getHistoryChat()
  // Promise.all([data, isNew]).then((result) => {
  //   skillsMessage.value.messages.push({
  //     content: 'Flora, you are the tallest in the family.',
  //     role: 'system',
  //   })
  //   setSkills(base64toJson(data.tips), 'system')
  // })
}

// 获取用户历史聊天内容
const getHistoryChat = () => {
  return new Promise<void>((resolve, reject) => {
    selectChart(pageId.value).then(async (res) => {
      const { code, data } = res
      if (code === 0) {
        const chatRecord = JSON.parse(data.chatRecord)
        recordList.value = chatRecord.map((item, index) => {
          return {
            type: item.role,
            origin: item.chat,
            audio_url: item.audio_url,
          }
        })
        //自动播放ai第一句
        if (recordList.value.length === 1) {
		  recordList.value[0].isPlay = true
		  let mp3Path = await onplayTitle(recordList.value[0].origin, 'English',0)
		  recordList.value[0].audio_url = mp3Path
        }
        skillsMessage.value.messages.push({
          content: 'Hello',
          role: 'user',
        })
        recordList.value.forEach((item, index) => {
          skillsMessage.value.messages.push({
            content: item.origin,
            role: item.type == 1 ? 'assistant' : item.type == 2 ? 'user' : '',
          })
        })
        //获取三个问题对话参考
        getChatAiTag(recordList.value[recordList.value.length - 1].origin)
      } else if (code != 0) {
        resolve()
      }
    })
  })
}

const translateLongTip = () => {
  uni.showToast({
    title: '翻译内容超长',
    duration: 2000,
    icon: 'none',
  })
}

// AI进行翻译
const handleFanyi = (value: string, index: number, rag: string) => {
  textTranslate(value)
    .then(
      (res) => {
        	recordList.value[index].result = res
        	recordList.value[index].isTranslate = true
      },
      () => {
        // translateLongTip()
      }
    )
    .catch(() => {
      // translateLongTip()
    })
}
// 停止播放动画
const clearStop = () => {
	recordList.value = recordList.value.map((item, i) => {
	  return {
		...item,
		isPlay: false,
	  }
	})
}
const setSkills = (res: string, type: string) => {
  let index = 0
  let allText = ''
  let resultStr = '' // ai返回的字符串
  if (type == 'system') {
    skillsMessage.value.messages.push({
      content: 'Hello',
      role: 'user',
    })
  }
  if (type == 'user') {
    skillsMessage.value.messages.push({
      content: res,
      role: 'user',
    })
  }
  recordList.value.push({
    type: 1,
    origin: '',
    result: '',
    isTranslate: false,
  })
  loadingStatus.value = 'loading'
  const requestTask = uni.request({
    url: `${BASE_URL}/enteacher/aichat`,
    timeout: 15000,
    responseType: 'text',
    method: 'POST',
    enableChunked: true,
    data: skillsMessage.value,
    success: async (response) => {
      skillsMessage.value.messages.push({
        content: resultStr,
        role: 'assistant',
      })
      //自动播放ai回答的内容
      let mp3Path = await onplayTitle(resultStr, 'English',recordList.value.length - 1)
	  recordList.value[recordList.value.length - 1].audio_url = mp3Path
      setTimeout(() => {
        getChatAiTag(resultStr)
      }, 1300)
      //将当前的ai回答语句传给服务端保存
      let params = {
        id: pageId.value,
        chat: platform.value == 'qwen' ? allTipsList.value.text : resultStr,
        role: 1,
        star: 0,
        url: '',
      }
      insertChart(params).then((res) => {})
    },
    fail: (error) => {},
  })
  requestTask.onChunkReceived(async function (res) {
    const data16 = buf2hex(res.data) // ArrayBuffer转16进制
    const text = hexToString(data16) // 16进制转字符串
    switch (platform.value) {
      case 'gpt':
        let gptStr = ''
        allText += text
		// console.log(allText)
        if (allText.indexOf('[DONE]') != -1) {
          let dataArrGpt = allText.split('data:')
          dataArrGpt.map((item, index) => {
            if (item != '' && item.indexOf('[DONE]') == -1) {
              let obj = JSON.parse(item)
              gptStr += ![undefined].includes(obj.choices[0].delta.content)
                ? obj.choices[0].delta.content
                : ''
            }
          })
          resultStr = gptStr
          const streamOutput = () => {
			console.log(gptStr.length,index,"gptStrgptStrgptStrgptStrgptStr")
            if (index != gptStr.length) {
              let currentText = gptStr.substring(0, index + 1)
              index++
              recordList.value[recordList.value.length - 1].origin = currentText
            } else {
			  loadingStatus.value = 'none'
              clearInterval(timer)
            }
          }
		  let timer = setInterval(streamOutput, 30)
          autoScroll()
          break
        }
    }
    autoScroll()
  })
}
// 获取对话参考
const getChatAiTag = async (value: string) => {
  let allText = ''
  let messageData = {
    platform: platform.value,
    messages: [
      ...skillsMessage.value.messages,
      {
        content:
          `Provide three reference answers based on the context of the conversation.${value}.Please output in only this JSON format:[{"line"\:"one"\},{"line"\:"two"\},{"line"\:"three"\}].Do not provide content unrelated to this format.Please refrain from providing introductory text.`,
        role: 'system',
      },
    ],
  }
  let str = ''
  const requestTask = uni.request({
    url: `${BASE_URL}/enteacher/aichat`,
    timeout: 15000,
    responseType: 'text',
    method: 'POST',
    enableChunked: true,
    data: messageData,
    success: (response) => {},
    fail: (error) => {},
  })
  requestTask.onChunkReceived(function (res) {
    const uint8Array = new Uint8Array(res.data)
    let text = String.fromCharCode.apply(null, uint8Array)
    // let text = res.data
    switch (platform.value) {
      case 'gpt':
        try {
          allText += text
          if (allText.indexOf('[DONE]') != -1) {
            let dataArrGpt = allText.split('data:')
            dataArrGpt.map((item, index) => {
              if (item != '' && item.indexOf('[DONE]') == -1) {
                let obj = JSON.parse(item)
                str += ![undefined].includes(obj.choices[0].delta.content)
                  ? obj.choices[0].delta.content
                  : ''
              }
            })
            if (str.indexOf('```json') != -1) {
              let obj = str.split('```json')[1].split('```')[0]
              let newStr = obj.replace(/\\n/g, '').replace(/\\/g, '')
              tipsList.value = JSON.parse(newStr)
            } else {
              tipsList.value = JSON.parse(str)
            }
          }
        } catch (err) {
          tipsList.value = [{line: "暂时还没有参考答案~" , catch: true}]
          // getChatAiTag(value)

        }

        break
    }
  })
}
const getUserMp3 = () => {
  return new Promise<void>((resolve, reject) => {
    let newArr: Iterable<number> = []
    frameBufferList.value.map((item, index) => {
      const newBuffer = new Uint8Array(item)
      newArr.push(...newBuffer)
    })
    const uint8Array = new Uint8Array(newArr)
    let view = encodeWAV(uint8Array.buffer, 1, 16000)
    let baseData = toBase64(view.buffer, 'normal')
    let fileName = new Date().getTime()
    let obj = {
      file_name: fileName + '.wav',
      base64_file: baseData, // Base64 编码的文件内容
      project_name: 'userMp3',
    }
    uploadAudio(obj).then((res) => {
      const { message, data } = res
      if (message === 'pong') {
        resolve(data.fileUrl)
      } else {
        frameBufferList.value = []
        reject({ code: '400', msg: '未返回图片' })
      }
    })
  })
}
// 长按录制
const startRecord = () => {
  clearStop()
  handleCloseVideo()
  animation.value = true
  connectWebSocket().then(async (res: string) => {
    let path = await getUserMp3()
    if (res != '') {
      recordList.value.push({
        type: 2,
        origin: res,
        result: '',
        filename: '',
        isTranslate: false,
        audio_url: path,
      })
      //将当前的ai回答语句传给服务端保存
      let params = {
        id: pageId.value,
        chat: res,
        role: 2,
        star: 1 || Number(res.fluency_score),
        audio_url: path,
      }
      insertChart(params).then((res) => {})
      setSkills(res, 'user')
      frameBufferList.value = []
    } else {
      uni.showToast({
        title: '未识别到文字',
        icon: 'none',
      })
      frameBufferList.value = []
    }
  })
  recorderManager.start({
    duration: 600000, // 600000（10 分钟）,默认值 60000（1 分钟）
    numberOfChannels: 1, // 录音通道数，有效值 1/2
    frameSize: 10,
    format: 'pcm', // 音频格式
    sampleRate: 16000, // 采样率
  })
}
// 松开停止
const endRecord = () => {
  animation.value = false
  recorderManager.stop()
}
const startWatch = () => {
  var lastFrame: never[] = []
  recorderManager.onStop(function (res) {
    // 监听最后一帧
    webSocketSend(lastFrame, true).then((res) => {
      if (res == 'success') {
      }
    })
    let tempFile = res.tempFilePath //音频文件地址
    // #ifdef MP-WEIXIN
    const fs = uni.getFileSystemManager()
    // 评分
    fs.readFile({
      // 拿到用户自己录制的音频保存
      filePath: tempFile,
      success: (res) => {},
    })
    // #endif
  })
  recorderManager.onFrameRecorded(function (res) {
    const { frameBuffer, isLastFrame } = res
    frameBufferList.value.push(frameBuffer)
    lastFrame = frameBuffer
    // 基础
    webSocketSend(frameBuffer, isLastFrame).then((res) => {
      if (res == 'success') {
      }
    })
  })
}
const getDetail = (id) => {
  return new Promise<void>((resolve, reject) => {
    getDialogueTopicDetail({ id: id }).then((res) => {
      const { code, data } = res
      if (code === 0) {
        setTitle.value = data.topicChinese
        uni.setNavigationBarTitle({
          title: setTitle.value, // 可以根据需要设置为任意字符串
        })
        curPromptTips.value = base64toJson(data.tips)
        //如果有历史记录，加入历史聊天记录上下文到参数
        skillsMessage.value.messages = [
          {
            content: curPromptTips.value,
            role: 'system',
          },
        ]

        if(data.prologue){
          prologue.value = data.prologue
          detailObj.value = data
        }

        resolve(data)
      }
    })
  })
}
const onplayTitle = async (value, type,index) => {
  if (!isUnload.value) {
    // Chinese中文 | English英文
    let res = await webSocketSendMp3(value, type)
    let newArr: any = []
    res.map((item: string, index: any) => {
      const arrayBuffer = uni.base64ToArrayBuffer(item)
      const newBuffer = new Uint8Array(arrayBuffer)
      newArr.push(...newBuffer)
    })
    let uint8Array = new Uint8Array(newArr)
    const newUrl: any = uni.createBufferURL(uint8Array.buffer)
    if (!isUnload.value) {
		clearStop()
		recordList.value[index].isPlay = true
		  handleClickVideo(newUrl).then(() => {
			recordList.value[index].isPlay = false
		})
	}
	return newUrl
  }
}
onPageScroll((e) => {})
</script>

<template>
  <page-meta :page-style="showPopup?'overflow:hidden':''"></page-meta>
  <xm-container :loading="loading">
    <template v-slot="{ message }">
      <view class="top-bg" />
      <!-- 内容 -->
      <view class="page">
        <!-- 内容部分 -->
        <scroll-view
          class="tn-text-justify outscroll"
          style="padding-bottom: 180rpx;"
          scroll-top="10000"
        >
          <view class="mlr-15" v-for="(item, index) in recordList" :key="index">
            <view
              class="tn-flex tn-flex-row-between tn-flex-col-center"
              v-if="item.type == 1"
            >
              <view class="justify-content-item">
                <view class="tn-flex tn-flex-col-top tn-flex-row-left">
                  <view class="tn-padding-right tn-color-black">
                    <view class="tn-flex tn-flex-col-center">
                      <view
                        class="tn-margin-sm tn-padding-sm tn-bg-white"
                        style="
                          max-width: 62vw;
                          border-radius: 0 20rpx 20rpx 20rpx;
                        "
                      >
                        <view class="flex flex-js-sb">
                          <view
                            class="mr-4 origin-box"
                            style="min-width: 120rpx"
                          >
                            <view v-if="item.origin">{{ item.origin }} </view>
                            <view v-else class="loader-40"></view>
                          </view>
                          <image
                            v-if="item.origin"
                            style="display: inline-table; flex-shrink: 0"
                            class="radius-50 pngStyle"
                            :class="item.isPlay ? 'is-translate' : ''"
                            :src="item.isPlay ? playIconGif : playIconPng"
                            @click="handleClick('play', item, index, 1)"
                          ></image>
                        </view>
                        <view v-if="item.result">
                          <view
                            class="line mtb-8"
                            style="border-bottom: 1rpx solid #dcdcdc"
                          >
                          </view>
                          <view
                            class="tn-color-black bg-color-white"
                            style="max-width: 450rpx"
                          >
                            <view>{{ item.result }} </view>
                            <!-- 	<view style="color:blue"><text
																class="font-w-600 mr-5">rag:</text>{{ item.ragResult }}
														</view> -->
                          </view>
                        </view>
                      </view>
                      <view class="" v-if="item.origin">
                        <image
                          style="width: 40rpx; height: 40rpx"
                          :class="item.isTranslate ? 'is-translate' : ''"
                          :src="
                            item.isTranslate ? translateBlue : translateBlack
                          "
                          @click="handleFanyi(item.origin, index, item.rag)"
                        >
                        </image>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
              <view class="justify-content-item"></view>
            </view>
            <view
              class="tn-flex tn-flex-row-between tn-flex-col-center"
              v-if="item.type == 2"
            >
              <view class="justify-content-item"></view>
              <view class="justify-content-item">
                <view class="tn-flex tn-flex-col-top tn-flex-row-left">
                  <view class="tn-padding-left tn-color-black">
                    <view class="tn-flex tn-flex-col-center">
                      <image
                        style="width: 40rpx; height: 40rpx"
                        :class="item.isTranslate ? 'is-translate' : ''"
                        :src="item.isTranslate ? translateBlue : translateBlack"
                        @click="handleFanyi(item.origin, index)"
                      ></image>
                      <view
                        class="tn-margin-sm tn-padding-sm f-color-text flex flex-ai-center"
                        style="max-width: 62vw"
                      >
                        <view>
                          <view class="flex flex-js-sb">
                            <view
                              class="mr-4 origin-box"
                              style="max-width: 380rpx"
                            >
                              {{ item.origin }}
                            </view>
                            <image
                              class="radius-50 pngStyle"
                              :class="item.isPlay ? 'is-translate' : ''"
                              :src="
                                item.isPlay
                                  ? playWhiteIconGif
                                  : playWhiteIconPng
                              "
                              @click="handleClick('play', item, index, 1)"
                            ></image>
                          </view>
                          <view v-if="item.result">
                            <view
                              class="line mtb-8"
                              style="border-bottom: 1rpx solid #dcdcdc"
                            >
                            </view>
                            <view
                              class="tn-color-white"
                              style="max-width: 450rpx"
                            >
                              {{ item.result }}
                            </view>
                          </view>
                        </view>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
        <!-- 底部按钮 -->
        <view class="footer">
          <view class="flex flex-js-sb flex-ai-center">
            <!-- <view class="text-center footer-btn" @click="handleClick('open')">
              <image
                style="width: 75rpx; height: 75rpx"
                class="radius-50"
                src="../../../static/imgs/reference.png"
              >
              </image>
              <view class="font-size-12 font-color-c666">对话参考</view>
              
            </view> -->
            <view class="btn-box" @click="goBack">
              <view class="iconBox">
                <span>
                  <TnIcon
                    name="power"
                    size="40rpx"
                    color="#818181"
                  />
                </span>
              </view>
              <view class="btn-item"
                >关闭对话</view
              >
            </view>
            <view class="footer-btn">
              <view
                class="footer-btn-active flex flex-ai-center flex-js-center"
              >
                <image
                  style="width: 72rpx; height: 72rpx"
                  class="radius-50 icon"
                  @touchstart.stop="startRecord"
                  @touchend.stop="endRecord"
                  src="../../../static/imgs/index/expert-video.png"
                ></image>
              </view>
              <view>按住说话</view>
            </view>
            <!-- <view class="footer-btn" @click="handleClick('reload')">
					<image style="width: 75rpx; height: 75rpx" class="radius-50" :class="isAnimation ? 'refish' : ''"
						src="../../../static/imgs/refresh.png"></image>
					<view class="font-size-12 font-color-c666">重新对话</view>
				</view> -->
            <view class="btn-box" @click="handleClick('reload')">
              <view :class="isAnimation ? 'active-iconBox' : 'iconBox'">
                <span :class="isAnimation ? 'refish' : ''">
                  <TnIcon
                    name="refresh"
                    :size="isAnimation ? '80rpx' : '50rpx'"
                    :color="isAnimation ? '#ffffff' : '#818181'"
                  />
                </span>
              </view>
              <view :class="isAnimation ? 'active-btn-item' : 'btn-item'"
                >重新对话</view
              >
            </view>
          </view>
        </view>
      </view>
      <!-- 提示答案 -->
      <TnPopup
        v-model="showPopup"
        class="popup-box"
        open-direction="bottom"
        :radius="30"
        top="54px"
      >
        <scroll-view class="plr-16 popup-main">
          <view class="popup-title flex flex-js-sb flex-ai-center">
            <view></view>
            <view class="font-size-16 font-color-c333 font-w-bold"
              >你可以这样说</view
            >
            <image
              class="close-icon"
              src="../../../static/imgs/close.png"
              @click="handleClose"
            ></image>
          </view>
          <view class="popup-contnet mt-6">
            <view
              style="text-align: center"
              class="mt-40"
              v-if="tipsList.length == 0"
            >
              <view class="loader">
                <view class="circle loading1"></view>
                <view class="circle loading2"></view>
                <view class="circle loading3"></view>
                <view class="circle loading4"></view>
                <view class="circle loading5"></view>
                <view class="circle loading6"></view>
                <view class="circle loading7"></view>
                <view class="circle loading8"></view>
              </view>
              <view class="mt-12 loader-text">加载中，请稍等</view>
            </view>
            <view v-else>
              <view
                class="flex-1 flex items pa-12 br-16 flex-js-sb mb-12 bg-color-white"
                v-for="(item, index) in tipsList"
                :key="index"
              >
                <view class="" v-if="!item.catch">
                  <view class="flex">
                    <view
                      class="mr-8 items-line"
                      style="word-wrap:break-word;"
                      @click="handleClick('send', item.line)"
                    >
                      {{ item.line }}
                    </view>
                    <view class="flex mt-2">
                      <image
                        class="play-icon mr-6"
                        :class="item.isPlay ? 'is-translate' : ''"
                        :src="item.isPlay ? playIconGif : playIconPng"
                        mode=""
                        @click="handleClick('play', item, index, 2)"
                      >
                      </image>
                      <image
                        class="translate-icon"
                        :class="item.isTranslate ? 'is-translate' : ''"
                        :src="item.isTranslate ? translateBlue : translateBlack"
                        mode=""
                        @click="handleClick('fanyi', item.line, index)"
                      ></image>
                    </view>
                  </view>
                  <view class="split-line mtb-8" v-if="item.translate"></view>
                  <view class="mt-4" v-if="item.translate">{{
                    item.translate
                  }}</view>
                </view>
                <view v-else> {{item.line}}</view>
              </view>
            </view>
          </view>
          <view class="popup-footer pt-10">
            <view class="footer-btn flex flex-ai-center flex-js-center">
              <image
                class="icon radius-50"
                src="../../../static/imgs/index/expert-video.png"
                @touchstart.stop="startRecord"
                @touchend.stop="endRecord"
              >
              </image>
            </view>
            <view class="font-bold font-size-14 font-color-c191919 mt-4"
              >按住说话</view
            >
          </view>
        </scroll-view>
      </TnPopup>
      <!-- 语音音阶动画 长按说话时的动画 -->
      <view class="prompt" v-if="animation">
        <section class="dots-container">
          <view class="dot"></view>
          <view class="dot"></view>
          <view class="dot"></view>
          <view class="dot"></view>
          <view class="dot"></view>
        </section>
        <text>说话中...</text>
      </view>
    </template>
  </xm-container>
</template>

<style lang="scss" scoped>
@import './styles/index1.scss';

.pngStyle {
  width: 40rpx;
  height: 40rpx;
}

.refish {
  transition: 1s;
  transform: rotate(360deg);
}

.origin-box {
  word-wrap: wrap;
  text-align: left;
  // word-break: break-all;
}

.btn-box {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 200rpx;

  .iconBox {
    width: 72rpx;
    height: 72rpx;
    background: #ffffff;
    box-shadow: 0rpx 8rpx 8rpx 0rpx #f8f8f8;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .active-iconBox {
    width: 100rpx;
    height: 100rpx;
    background: linear-gradient(90deg, #4b49e8 0%, #6b8bfb 100%);
    box-shadow: 0rpx 8rpx 8rpx 0rpx #f8f8f8;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .refish {
    transition: 1s;
    transform: rotate(360deg);
  }

  .btn-item {
    font-weight: 400;
    font-size: 24rpx;
    color: #666666;
    line-height: 28rpx;
    margin-top: 12rpx;
  }

  .active-btn-item {
    color: #191919;
    font-weight: 400;
    font-size: 24rpx;
    line-height: 28rpx;
    margin-top: 20rpx;
  }
}

.is-translate {
  animation: btnSpin 0.2s 0s 1;
  color: red;
}

@keyframes btnSpin {
  0% {
    scale: 0.8;
  }

  25% {
    scale: 1;
  }

  50% {
    scale: 1.2;
  }

  75% {
    scale: 1;
  }

  100% {
    scale: 0.8;
  }
}
.loader-40 {
  width: 24rpx;
  height: 24rpx;
  border-radius: 50%;
  display: inline-block;
  position: relative;
  background: #fff;
  box-shadow:
    -40rpx 0 #e8e8ff,
    40rpx 0 #e8e8ff;
  animation: shadowPulse 2s linear infinite;
  margin-left: 45rpx;
}
@keyframes shadowPulse {
  33% {
    background: #e8e8ff;
    box-shadow:
      -40rpx 0 #4b49e8,
      40rpx 0 #e8e8ff;
  }
  66% {
    background: #4b49e8;
    box-shadow:
      -40rpx 0 #e8e8ff,
      40rpx 0 #e8e8ff;
  }
  100% {
    background: #e8e8ff;
    box-shadow:
      -40rpx 0 #e8e8ff,
      40rpx 0 #4b49e8;
  }
}
</style>
